import * as React from 'react';
import {render as renderSchema,toast,alert,confirm} from 'amis';
import { MessagePlugin as message } from "tdesign-react";
// import { getEnv } from 'mobx-state-tree';
// import { inject, observer } from 'mobx-react';
import axios from 'axios'
import request from '../../utils/requestAmis'
// @ts-ignore
import * as qs from 'qs';
import copyToClipboard  from 'copy-to-clipboard';
import { Action } from 'amis/lib/types';
import {useNavigate} from "react-router-dom";


interface RendererProps {
    schema?:any;
    [propName:string]:any;
};

// @inject("store")
// @ts-ignore
// @withRouter
// @observer
export default class Index extends React.Component<RendererProps> {
    env:any = null;

    handleAction = (e:any, action:Action) => {
        // 处理自定义的actionType
    }

    constructor(props:RendererProps) {
        super(props);
        const fetcher = ({url, method, data, config, headers}: any) => {
            config = config || {};
            config.headers = config.headers || {};
            config.withCredentials = false;

            // if (config.cancelExecutor) {
            //     config.cancelToken = new axios.CancelToken(config.cancelExecutor);
            // }

            config.headers = headers || {};
            config.method = method;

            if (method === 'get' && data) {
                config.params = data;
            } else if (data && data instanceof FormData) {
                // config.headers = config.headers || {};
                // config.headers['Content-Type'] = 'multipart/form-data';
            } else if (data
                && typeof data !== 'string'
                && !(data instanceof Blob)
                && !(data instanceof ArrayBuffer)
            ) {
                // data = JSON.stringify(data);
                // config.headers = config.headers || {};
                config.headers['Content-Type'] = 'application/json';
            }

            data && (config.data = data);

            return request(url, config);
        };
        const notify = (type: 'success' | 'error' | 'info', msg: string) => {
            message[type] && msg ? message[type](msg) : console.warn('[Notify]', type, msg);
        };
        const copy = (contents: string, options: any = {}) => {
            const ret = copyToClipboard(contents, options);
            ret && (!options || options.shutup !== true) && message.info('内容已拷贝到剪切板');
            return ret;
        };
        // const history = props.history;

        const normalizeLink = (to:string) => {
            if (/^\/api\//.test(to)) {
                return to;
            }
            to = to || '';
            const location = window.location;
            if (to && to[0] === '#') {
                to = location.pathname + location.search + to;
            } else if (to && to[0] === '?') {
                to = location.pathname + to;
            }
            const idx = to.indexOf('?');
            const idx2 = to.indexOf('#');
            let pathname =  ~idx ? to.substring(0, idx) : ~idx2 ? to.substring(0, idx2) : to;
            let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';
            let hash = ~idx2 ? to.substring(idx2) : '';
            if (!pathname) {
                pathname = location.pathname;
            }else if (pathname[0] != '/' && !/^https?\:\/\//.test(pathname)) {
                let relativeBase = location.pathname;
                const paths = relativeBase.split('/');
                paths.pop();
                let m;
                while ((m = /^\.\.?\//.exec(pathname))) {
                    if (m[0] === '../') {
                        paths.pop();
                    }
                    pathname = pathname.substring(m[0].length);
                }
                pathname = paths.concat(pathname).join('/');
            }
            return pathname + search + hash;
        }

        this.env = {
            session: 'global',
            updateLocation: props.updateLocation || ((location:string, replace:boolean) => {
                // if (location === 'goBack') {
                //     return History.goBack();
                // }
                // History[replace ? 'replace' : 'push']({path:normalizeLink(location)});
            }),
            isCurrentUrl: (to:string) => {
                const link = normalizeLink(to);
                const location = window.location;
                let pathname = link;
                let search = '';
                const idx = link.indexOf('?');
                if (~idx) {
                    pathname = link.substring(0, idx);
                    search = link.substring(idx);
                }
                if (search) {
                    if (pathname !== location.pathname || !location.search) {
                        return false;
                    }
                    const query = qs.parse(search.substring(1));
                    const currentQuery = qs.parse(location.search.substring(1));
                    return Object.keys(query).every(key => query[key] === currentQuery[key]);
                } else if (pathname === location.pathname) {
                    return true;
                }
                return false;
            },
            jumpTo: props.jumpTo || ((to:string, action?:any) => {
                if (to === 'goBack') {
                    return window.history.back()
                }
                to = normalizeLink(to);
                if (action && action.actionType === 'url') {
                    action.blank === false ? (window.location.href = to) : window.open(to);
                    return;
                }
                if (/^https?:\/\//.test(to)) {
                    window.location.href = to;
                } else {
                    const navigate = useNavigate()
                    navigate(to)
                }
            }),
            fetcher,
            isCancel: (value: any) => (axios as any).isCancel(value),
            notify,
            alert,
            confirm,
            copy,
        };
    }

    render() {
        const {
            schema,
            onAction,
            ...rest
        } = this.props;
        return renderSchema(schema, {
            onAction: onAction || this.handleAction,
            theme: 'cxd',
            ...rest
        }, this.env);
    }
}
